package com.linxiao.call.controller;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSONObject;
import com.linxiao.call.domain.CrmOutCallCdr;
import com.linxiao.call.service.ICrmOutCallCdrService;
import com.linxiao.call.vo.CrmCallRecordCallBackParamVo;
import com.linxiao.call.vo.CrmCallRecordCallBackVo;
import com.monitorjbl.xlsx.StreamingReader;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.CrmConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.enums.CrmCdrCallTypeEnum;
import com.ruoyi.common.enums.CrmCdrStatusEnum;
import com.ruoyi.common.utils.*;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.utils.sign.Md5Utils;
import com.ruoyi.system.service.ISysUserService;
import org.apache.poi.ss.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 【外呼通话记录】Controller
 *
 * @author zhoudong
 */
@RestController
@RequestMapping("/crm/cdr")
public class CrmOutCallCdrController extends BaseController {
    private final Logger log = LoggerFactory.getLogger(this.getClass());
    @Resource
    private ICrmOutCallCdrService crmOutCallCdrService;
    @Resource
    private ISysUserService sysUserService;

    /**
     * 查询【外呼通话记录】列表
     */
    @GetMapping("/list")
    @Log(title = "【外呼通话记录列表】", businessType = BusinessType.LIST)
    public TableDataInfo list(CrmOutCallCdr crmOutCallCdr) {
        List<CrmOutCallCdr> list = crmOutCallCdrService.selectCrmOutCallCdrList(crmOutCallCdr);
        return getDataTable(list);
    }

    /**
     * 导出【外呼通话记录】列表
     */
    @Log(title = "【导出外呼通话记录】", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, CrmOutCallCdr crmOutCallCdr) {
        List<CrmOutCallCdr> list = crmOutCallCdrService.selectCrmOutCallCdrListExport(crmOutCallCdr);
        ExcelUtil<CrmOutCallCdr> util = new ExcelUtil<CrmOutCallCdr>(CrmOutCallCdr.class);
        util.exportExcel(response, list, "【通话记录】数据");
    }

    /**
     * 获取【外呼通话记录】详细信息
     */
    @Log(title = "【外呼通话记录详细信息】", businessType = BusinessType.INSERT)
    @GetMapping(value = "/detail")
    public AjaxResult getInfo(Long id, String cdrMainUniqueId) {
        return AjaxResult.success(crmOutCallCdrService.selectCrmOutCallCdrById(id, cdrMainUniqueId));
    }

    /**
     * 新增【外呼通话记录】
     */
    @RequestMapping("/add")
    @Log(title = "【新增外呼通话记录】", businessType = BusinessType.INSERT)
    public AjaxResult add(@RequestBody CrmOutCallCdr crmOutCallCdr) {
        log.info("新增外呼通话记录：crmOutCallCdr = {}", JSONObject.toJSONString(crmOutCallCdr));
        if (Objects.isNull(crmOutCallCdr)) {
            return AjaxResult.error("新增外呼通话记录 实体参数不能为空");
        }
        return crmOutCallCdrService.insertCrmOutCallCdr(crmOutCallCdr);
    }

    @RequestMapping("/getRecordCallBack")
    @Log(title = "【录音回调接口】", businessType = BusinessType.INSERT)
    public AjaxResult getRecordCallBack(@RequestBody CrmCallRecordCallBackParamVo crmCallRecordCallBackParamVo) {

        log.info("外呼记录录音回调：crmCallRecordCallBackParamVo = {}", JSONObject.toJSONString(crmCallRecordCallBackParamVo));
        if (Objects.nonNull(crmCallRecordCallBackParamVo) && StringUtils.isEmpty(crmCallRecordCallBackParamVo.getCdr_enterprise_id())) {
            log.info("录音回调参数 [cdr_enterprise_id] = {}", crmCallRecordCallBackParamVo.getCdr_enterprise_id());
            return AjaxResult.error("录音回调参数 [cdr_enterprise_id] 不能为null");
        }
        if (StringUtils.isEmpty(crmCallRecordCallBackParamVo.getCdr_unique_id())) {
            log.info("录音回调参数 [cdr_unique_id] = {}", crmCallRecordCallBackParamVo.getCdr_unique_id());
            return AjaxResult.error("录音回调参数 [cdr_unique_id] 不能为null");
        }
        if (StringUtils.isEmpty(crmCallRecordCallBackParamVo.getCdr_call_type())) {
            log.info("录音回调参数 [cdr_call_type] = {}", crmCallRecordCallBackParamVo.getCdr_call_type());
            return AjaxResult.error("录音回调参数 [cdr_call_type] 不能为null");
        }
        boolean res = CrmConstants.TR_CDR_CALL_TYPE_1.equals(crmCallRecordCallBackParamVo.getCdr_call_type())
                || CrmConstants.TR_CDR_CALL_TYPE_4.equals(crmCallRecordCallBackParamVo.getCdr_call_type())
                || CrmConstants.TR_CDR_CALL_TYPE_6.equals(crmCallRecordCallBackParamVo.getCdr_call_type());
        if (!res) {
            log.info("录音回调参数 [cdr_call_type] = {}", crmCallRecordCallBackParamVo.getCdr_call_type());
            return AjaxResult.error("录音回调参数 [cdr_call_type] 取值有误");
        }
        CrmCallRecordCallBackVo crmCallRecordCallBackVo = new CrmCallRecordCallBackVo();
        crmCallRecordCallBackVo.setCdrEnterpriseId(crmCallRecordCallBackParamVo.getCdr_enterprise_id());
        crmCallRecordCallBackVo.setCdrUniqueId(crmCallRecordCallBackParamVo.getCdr_unique_id());
        crmCallRecordCallBackVo.setCdrRecordDuration(crmCallRecordCallBackParamVo.getCdr_record_duration());
        crmCallRecordCallBackVo.setCdrCallType(crmCallRecordCallBackParamVo.getCdr_call_type());

        crmCallRecordCallBackVo.setCdrMonitorType(crmCallRecordCallBackParamVo.getCdr_monitor_type());
        crmCallRecordCallBackVo.setRecordFile(crmCallRecordCallBackParamVo.getRecord_file());
        crmCallRecordCallBackVo.setRecordType(crmCallRecordCallBackParamVo.getRecord_type());

        return crmOutCallCdrService.getRecordCallBack(crmCallRecordCallBackVo);
    }

    /**
     * 更改坐席接口--天润生产
     *
     * @param cno
     * @param obClid
     * @return
     */
    @RequestMapping("/updateCno")
    public String updateCno(String cno, String obClid, String enterpriseId, String token) {
        long timestamp = new Date().getTime() / 1000;
        String update = "https://api-%s.cticloud.cn/interface/%s/agent/update";
        String recordUrl = String.format(update, 5, "v10");
        StringBuilder sb = new StringBuilder();
        sb.append("?");
        sb.append("validateType=2");
        sb.append("&enterpriseId=" + enterpriseId);
        sb.append("&timestamp=" + timestamp);
        sb.append("&cno=" + cno);
        sb.append("&obClidType=" + 2);
        sb.append("&obClid=" + obClid);
        sb.append("&sign=" + Md5Utils.hash(enterpriseId + timestamp + token));
        String url = recordUrl.concat(sb.toString());
        log.info("recordUrl = {}", url);
        String recordsResult = HttpUtil.get(url);
        log.info("Execute result[{}]", recordsResult);
        return recordsResult;
    }

    /**
     * 批量导入外呼记录
     *
     * @param file
     * @return
     */
    @PostMapping("/cdrBatchImportRecord")
    @Log(title = "【批量新增外呼通话记录】", businessType = BusinessType.INSERT)
    public AjaxResult batchImportRecord(@RequestPart("file") MultipartFile file) throws Exception {
        logger.info("批量新增外呼通话记录");
        ThreadUtil.execAsync(new Runnable() { //NOSONAR
            @Override
            public void run() {
                List<CrmOutCallCdr> crmOutCallCdrList = new ArrayList();
                try {
                    InputStream inputStream = file.getInputStream();
                    Workbook workbook = StreamingReader.builder()
                            .rowCacheSize(1000)
                            .bufferSize(1024)
                            .open(inputStream);
                    Sheet sheet = workbook.getSheetAt(0);
                    // 每1000条导入一次数据库
                    int batch = 1000;
                    // 总导入的行数
                    int lastRowNum = sheet.getLastRowNum();
                    // 是否需要批次导入
                    boolean needBatch = lastRowNum > batch;

                    //1.遍历所有的行
                    for (Row row : sheet) {
                        if (row.getRowNum() > 0) {
                            CrmOutCallCdr crmOutCallCdr = new CrmOutCallCdr();
                            // 1、unique_id
                            crmOutCallCdr.setCdrMainUniqueId(getValue(row.getCell(0)));
                            // 2、request_unique_id
                            crmOutCallCdr.setCdrRequestUniqueId(getValue(row.getCell(1)));
                            // 3、customer_number
                            crmOutCallCdr.setCdrCustomerNumber(getValue(row.getCell(2)));
                            // 4、customer_province
                            crmOutCallCdr.setCdrCustomerProvince(getValue(row.getCell(3)));
                            // 5、customer_city
                            crmOutCallCdr.setCdrCustomerCity(getValue(row.getCell(4)));
                            // 6、cno
                            crmOutCallCdr.setCdrCno(getValue(row.getCell(5)));
                            // 7、agent_number
                            crmOutCallCdr.setCdrAgentNumber(getValue(row.getCell(6)));
                            // 8、start_time
                            crmOutCallCdr.setCdrStartTime(StringUtils.isNotEmpty(getValue(row.getCell(7))) ? Long.valueOf(getValue(row.getCell(7))) : null);
                            // 9、end_time
                            crmOutCallCdr.setCdrEndTime(StringUtils.isNotEmpty(getValue(row.getCell(8))) ? Long.valueOf(getValue(row.getCell(8))) : null);
                            // 10、answer_time
                            crmOutCallCdr.setCdrAnswerTime(StringUtils.isNotEmpty(getValue(row.getCell(9))) ? Long.valueOf(getValue(row.getCell(9))) : null);
                            // 11、bridge_time
                            crmOutCallCdr.setCdrBridgeTime(StringUtils.isNotEmpty(getValue(row.getCell(10))) ? Long.valueOf(getValue(row.getCell(10))) : null);
                            // 12、callee_ringing_time
                            crmOutCallCdr.setCalleeRingingTime(StringUtils.isNotEmpty(getValue(row.getCell(11))) ? Long.valueOf(getValue(row.getCell(11))) : null);
                            // 13、call_type
                            crmOutCallCdr.setCdrCallType(CrmCdrCallTypeEnum.getByDesc(getValue(row.getCell(12))).getCode());
                            // 14、status
                            crmOutCallCdr.setCdrStatus(CrmCdrStatusEnum.getByDesc(getValue(row.getCell(13))).getCode());
                            // 15、end_reason
                            crmOutCallCdr.setCdrEndReason(getValue(row.getCell(14)));

                            // 16、clid
                            crmOutCallCdr.setCdrClid(getValue(row.getCell(15)));
                            // 17、agent_clid
                            crmOutCallCdr.setCustCalleeClid(getValue(row.getCell(16)));

                            // 18、record_file
                            crmOutCallCdr.setCosRecordUrl(getValue(row.getCell(17)));
                            // 19、enterprise_id
                            crmOutCallCdr.setCdrEnterpriseId(getValue(row.getCell(18)));

                            crmOutCallCdr.setCdrAgentNumber(crmOutCallCdr.getCdrCno());
                            try {//NOSONAR
                                if (StringUtils.isNotEmpty(crmOutCallCdr.getCosRecordUrl()) && !"NULL".equals(crmOutCallCdr.getCosRecordUrl())) {
                                    crmOutCallCdr.setCdrRecordFile1(crmOutCallCdr.getCosRecordUrl().substring(crmOutCallCdr.getCosRecordUrl().lastIndexOf("/") + 1));
                                }
                                StringBuilder builder = new StringBuilder();
                                builder.append(crmOutCallCdr.getCdrEndTime() == null ? "" : crmOutCallCdr.getCdrEndTime()).append("-").append(crmOutCallCdr.getCdrBridgeTime() == null ? "" : crmOutCallCdr.getCdrBridgeTime());
                                crmOutCallCdr.setCdrEndTimeCdrBridgeTime(builder.toString());

                                // 根据工号 获取二级部门id 和 当前员工所在部门ID
                                if (StringUtils.isNotEmpty(crmOutCallCdr.getCdrCno())) {
                                    SysUser sysUser = sysUserService.selectUserByAgentId(crmOutCallCdr.getCdrCno());
                                    if (Objects.nonNull(sysUser)) {
                                        crmOutCallCdr.setMchId(sysUser.getMchId());
                                        crmOutCallCdr.setDeptId(sysUser.getDeptId());
                                        crmOutCallCdr.setUserId(sysUser.getUserId());
                                    } else {
                                        logger.info("batchImportRecord没有获取到用户信息 cno={}", crmOutCallCdr.getCdrCno());
                                    }
                                }
                                crmOutCallCdr.setId(IdSeqGenerator.getInstance().getId());
                                crmOutCallCdr.setStartTime(DateUtils.getTime());
                                String cdrCustomerNumber = crmOutCallCdr.getCdrCustomerNumber();
                                // 加密存储 手机号
                                // 脱敏手机号
                                crmOutCallCdr.setMobileHidden(EncryptContent.replaceAction(cdrCustomerNumber));
                                // 默认外呼
                                crmOutCallCdr.setCdrCallType(Long.valueOf(CrmConstants.TR_CDR_CALL_TYPE_4));

                                // 3.分批数据处理
                                if (needBatch && crmOutCallCdrList.size() > batch) {
                                    logger.info("--------------每1000条数据，执行业务逻辑,--------------");
                                    int count = crmOutCallCdrService.batchInsertCrmOutCallCdr(crmOutCallCdrList);
                                    if (count == 0) {
                                        logger.info("batchImportRecord.批量新增失败 ");
                                    }

                                    // 执行完成后，list必须clear
                                    crmOutCallCdrList.clear();
                                }
                                // 暂存到list中
                                crmOutCallCdrList.add(crmOutCallCdr);

                            } catch (Exception e) {
                                logger.info("batchImportRecord解析录音文件名失败 e={}", e);
                            }
                        }
                    }
                } catch (Exception e) {
                    logger.info("batchImportRecord.eror 执行异常 {}", e);
                } finally {
                    if (crmOutCallCdrList.size() > 0) {
                        crmOutCallCdrService.batchInsertCrmOutCallCdr(crmOutCallCdrList);
                        logger.info("batchImportRecord.finally 执行批量新增");
                    }
                }
            }
        });

        return AjaxResult.success();
    }


    private static String getValue(Cell xCell) {

        if (xCell == null) {
            return "";
        }
        if (xCell.getCellType() == CellType.BOOLEAN) {
            return String.valueOf(xCell.getBooleanCellValue());
        } else if (xCell.getCellType() == CellType.NUMERIC) {

            return Double.valueOf(xCell.getNumericCellValue()).longValue() + "";
        } else if (xCell.getCellType() == CellType.STRING) {
            if (xCell.getStringCellValue().equals("NULL")) {
                return "";
            }
            return xCell.getStringCellValue();
        } else {
            return "";
        }
    }


    @GetMapping("/cdrBatchUpdateRecord")
    @Log(title = "【批量更新外呼通话记录】", businessType = BusinessType.INSERT)
    public AjaxResult cdrBatchUpdateRecord(CrmOutCallCdr crmOutCallCdr) {
        log.info("批量更新外呼通话记录");
        ThreadUtil.execAsync(() -> {
            AjaxResult ajaxResult = crmOutCallCdrService.cdrBatchUpdateRecord(crmOutCallCdr);
            log.info("cdrBatchUpdateRecord.ajaxResult={}",JSONObject.toJSONString(ajaxResult));
        });

        return AjaxResult.success();
    }

}
